package com.novel.config;



import com.fasterxml.jackson.databind.exc.InvalidFormatException;
import com.mysql.cj.jdbc.exceptions.MysqlDataTruncation;
import com.novel.constants.ResultEnum;
import com.novel.exception.ArgumentException;
import com.novel.exception.BusinessException;
import com.novel.utils.ResultVO;
import com.novel.utils.ResultVoUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import javax.servlet.http.HttpServletRequest;

/**
 * @author huawei
 */
@ControllerAdvice
@ConditionalOnWebApplication
public class DefaultResponseHandler implements ResponseBodyAdvice<Object> {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    private static final String RESPONSE_RESULT_ANN = "RESPONSE-RESULT-ANN";

    /**
     * 拦截参数异常
     *
     * @author hm
     */
    @ExceptionHandler(ArgumentException.class)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public ResultVO<?> notFount(ArgumentException e) {
        logger.warn("参数异常:{}", e.getMessage());
        e.printStackTrace();
        return ResultVoUtil.error(e.getCode(), e.getMessage());
    }

    /**
     * 拦截业务异常
     *
     * @author hm
     */
    @ExceptionHandler(BusinessException.class)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public ResultVO<?> notFount(BusinessException e) {
        logger.error("业务异常:{}", e.getErrorMessage(), e);
        return ResultVoUtil.error(e.getCode(), e.getErrorMessage());
    }




    /**
     * 拦截未知的运行时异常
     *
     * @author hm
     */
    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public ResultVO<?> notFount(Exception e) {
        logger.error("运行时异常:{}", e.getMessage(), e);
        return ResultVoUtil.result(ResultEnum.INNER_ERROR);
    }


    @Override
    public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
        ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (sra == null) {
            return false;
        }
        HttpServletRequest request = sra.getRequest();
        Object responseResult = request.getAttribute(RESPONSE_RESULT_ANN);
        return responseResult != null;
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter methodParameter,
                                  MediaType mediaType,
                                  Class<? extends HttpMessageConverter<?>> aClass,
                                  ServerHttpRequest serverHttpRequest,
                                  ServerHttpResponse serverHttpResponse) {
        if (body instanceof ResultVO) {
            return body;
        } else if (body instanceof String) {
            return ResultVoUtil.success(body).convert();
        } else {
            return body == null ? ResultVoUtil.success() : ResultVoUtil.success(body);
        }
    }
}
